//
//  SpecificationStore.swift
//  XingCeHelper
//
//  Created by 申铭 on 2022/10/19.
//

import Foundation
import CoreData

let kSpecification = "Specification"

class SpecificationStore {
    
    static func saveOrUpdate(specifications: [SpecificationModel]) {
        let managedContext = CoreDataStack.shared.managedContext
        
        for specification in specifications {
            let originalText = specification.originalText ?? ""
            let specificationText = specification.specificationText ?? ""
            let measureText = specification.measureText ?? ""
            
            if let specifi = find(originalText: originalText, specificationText: specificationText) { // 有，改
                specifi.category = specification.category
                specifi.originalText = originalText
                specifi.specificationText = specificationText
                specifi.measureText = measureText
                specifi.type = Int32(specification.type.rawValue)
            } else { // 无，加
                let specifi = NSEntityDescription.insertNewObject(forEntityName: kSpecification, into: managedContext) as! Specification
                specifi.category = specification.category
                specifi.originalText = originalText
                specifi.specificationText = specificationText
                specifi.measureText = measureText
                specifi.weight = 50
                specifi.isShow = true
                specifi.type = Int32(specification.type.rawValue)
            }
        }
        
        do {
            try managedContext.save()
            print("保存或修改成功")
        } catch {
            print("操作失败：\(error)")
        }
    }
    
    static func query(type: SpecificationType) -> [Specification] {
        let managedContext = CoreDataStack.shared.managedContext

        let fetchRequest = NSFetchRequest<Specification>(entityName:kSpecification)
        let predicate = NSPredicate(format: "type == %d", type.rawValue) // 设置查询条件
        fetchRequest.predicate = predicate
        
        let sortDesc = NSSortDescriptor(key: "weight", ascending: false)
        fetchRequest.sortDescriptors = [sortDesc]

        do {
            let fetchedObjects = try managedContext.fetch(fetchRequest)
            return fetchedObjects
        } catch {
            print("错误：\(error)")
        }
        
        return [Specification]()
    }
    
    static func query() -> NSFetchedResultsController<Specification> {
        let managedContext = CoreDataStack.shared.managedContext

        let fetchRequest = NSFetchRequest<Specification>(entityName: kSpecification)
        let predicate = NSPredicate(value: true)
        fetchRequest.predicate = predicate
        
        // 排序
        let sortDesc = NSSortDescriptor(key: "weight", ascending: false)
        fetchRequest.sortDescriptors = [sortDesc]
        
        // 查询并分组
        let fetchedRC = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedContext, sectionNameKeyPath: nil, cacheName: nil)
        
        do {
            try fetchedRC.performFetch()
        } catch let error as NSError {
            print("Error: \(error.userInfo)")
        }

        return fetchedRC
    }
    
    static func find(originalText: String?, specificationText: String?) -> Specification? {
        let managedContext = CoreDataStack.shared.managedContext
        let fetchRequest = NSFetchRequest<Specification>(entityName:kSpecification)
        let predicate = NSPredicate(format: "originalText == %@ OR specificationText == %@", originalText ?? "", specificationText ?? "") // 设置查询条件
        fetchRequest.predicate = predicate

        do {
            let fetchedObjects = try managedContext.fetch(fetchRequest)
            return fetchedObjects.first
        } catch {
            print("错误：\(error)")
        }
        
        return nil
    }
    
    static func find(originalText: String?) -> Specification? {
        guard let originalText = originalText else { return nil }
        
        let managedContext = CoreDataStack.shared.managedContext
        let fetchRequest = NSFetchRequest<Specification>(entityName:kSpecification)
        let predicate = NSPredicate(format: "originalText == %@", originalText) // 设置查询条件
        fetchRequest.predicate = predicate

        do {
            let fetchedObjects = try managedContext.fetch(fetchRequest)
            return fetchedObjects.first
        } catch {
            print("错误：\(error)")
        }
        
        return nil
    }
    
    static func changeWeight(title: String, weight: Int, oper: WeightOper) {
        guard let specifi = find(originalText: title) else { return }
        
        if oper == .add { // 加
            specifi.weight = specifi.weight + Int32(weight)
        } else if oper == .subtract { // 减
            specifi.weight = specifi.weight - Int32(weight)
        }
        
        do {
            try CoreDataStack.shared.managedContext.save()
        } catch {
            print("错误：\(error)")
        }
    }
    
    static func getCount() -> Int {
        let fetchquest = NSFetchRequest<NSFetchRequestResult>(entityName: kSpecification)
        do {
            return try CoreDataStack.shared.managedContext.count(for: fetchquest)
        } catch {
            print("错误：\(error)")
        }
        return 0
    }
    
    /// 删除
    /// - Parameter title: 标题
    static func delete(text: String) {
        let managedContext = CoreDataStack.shared.managedContext
        if let idiom = find(originalText: text, specificationText: nil) {
            managedContext.delete(idiom)
        }
        do {
            try managedContext.save()
            print("操作成功")
        } catch {
            print("操作失败：\(error)")
        }
    }
    
    static func deleteAll() {
        let managedContext = CoreDataStack.shared.managedContext
        let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: kSpecification)
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)
        deleteRequest.resultType = .resultTypeObjectIDs
        
        do {
            let result = try managedContext.execute(deleteRequest) as! NSBatchDeleteResult
            let changes: [AnyHashable: Any] = [
                NSDeletedObjectsKey: result.result as! [NSManagedObjectID]
            ]
            // 更新内存内容，否则无法刷新tableview中的数据
            NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [managedContext])
            try managedContext.save()
            print("操作成功")
        } catch {
            print("操作失败：\(error)")
        }
        
    }
}
